﻿namespace YunQue.IOC
{
    /// <summary>
    /// 自动注册
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 自动注册所有实现了 IScoped 的服务为 Scoped
        /// </summary>
        /// <param name="services">IServiceCollection</param>
        public static IServiceCollection AddScopedServicesFromAssembly(this IServiceCollection services)
        {
            // 获取所有实现了 IScoped 的类型
            var assemblies = AppDomain.CurrentDomain.GetAssemblies().SelectMany(p => p.GetTypes());
            var scopedTypes = assemblies.Where(t => t.GetInterfaces().Contains(typeof(IScoped)));
            foreach (var type in scopedTypes)
            {
                
                //注册 IService 接口
                var serviceInterface = type.GetInterfaces().FirstOrDefault(i => i.Name == "I" + type.Name);
                if (serviceInterface != null)
                {
                    services.AddScoped(serviceInterface, type);
                }
                else
                {
                    // 注册类型为 Scoped
                    services.AddScoped(type);
                }
            }
            return services;
        }
        /// <summary>
        /// 自动注册所有实现了 ISingleton 的服务为 Singleton
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddSingletonServicesFromAssembly(this IServiceCollection services)
        {
            // 获取所有实现了 ISingleton 的类型
            var assemblies = AppDomain.CurrentDomain.GetAssemblies().SelectMany(p => p.GetTypes());
            var singletonTypes = assemblies.Where(t => t.GetInterfaces().Contains(typeof(ISingleton)));
            foreach (var type in singletonTypes)
            {
                
                //注册 IService 接口
                var serviceInterface = type.GetInterfaces().FirstOrDefault(i => i.Name == "I" + type.Name);
                if (serviceInterface != null)
                {
                    services.AddSingleton(serviceInterface, type);
                }
                else
                {
                    // 注册类型为 Singleton
                    services.AddSingleton(type);
                }
            }
            return services;
        }
        /// <summary>
        /// 自动注册所有实现了 ITransient 的服务为 Singleton
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddTransientServicesFromAssembly(this IServiceCollection services)
        {
            // 获取所有实现了 ITransient 的类型
            var assemblies = AppDomain.CurrentDomain.GetAssemblies().SelectMany(p => p.GetTypes());
            var transientTypes = assemblies.Where(t => t.GetInterfaces().Contains(typeof(ITransient)));
            foreach (var type in transientTypes)
            {
               
                //注册 IService 接口
                var serviceInterface = type.GetInterfaces().FirstOrDefault(i => i.Name == "I" + type.Name);
                if (serviceInterface != null)
                {
                    services.AddTransient(serviceInterface, type);
                }
                else
                {
                    // 注册类型为 ITransient
                    services.AddTransient(type);
                }
            }
            return services;

        }
        /// <summary>
        /// 注册所有DI
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection AddAllDI(this IServiceCollection services)
        {
            var allAssembliesTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(p => p.GetTypes());
            var scopedTypes = allAssembliesTypes.Where(t => t.GetInterfaces().Contains(typeof(IScoped)));
            var singletonTypes = allAssembliesTypes.Where(t => t.GetInterfaces().Contains(typeof(ISingleton)));
            var transientTypes = allAssembliesTypes.Where(t => t.GetInterfaces().Contains(typeof(ITransient)));
            foreach (var type in scopedTypes)
            {
                services.AddScoped(type);
            }
            foreach (var type in singletonTypes)
            {
                services.AddSingleton(type);
            }
            foreach (var type in transientTypes)
            {
                services.AddTransient(type);
            }
            return services;
        }
    }
}
